#pragma once

#include <cstdint>

#include <SDL_keycode.h>
#include <SDL_scancode.h>

//////////////////////////////////////////////////////////////////////////
//
// Keyboard State class that stores:
//    - state of each key (pressed or not pressed)
//    - key events (recent key pressed or released)
// It does not consider a key repeat event as a key event
//
//////////////////////////////////////////////////////////////////////////

struct SDL_KeyboardEvent;

enum class keyState : uint8_t {
    NOT_PRESSED = 0,
    PRESSED
};

enum class keyEventState : uint8_t {
    NO_EVENT = 0,
    RELEASED,
    PRESSED
};

// You can index arrays using SDL Key Scan Codes
struct KeyboardState {        
    // State of each key (pressed or not pressed)
    const uint8_t* mKeysState;

    // State of events about a key
    // You can check if in the current frame
    // a key was pressed, released or 
    // it did not trigger an event
    keyEventState* mKeyEventState;

    // Stores the number of keys
    // Once initializes this should not be changed
    int mNumKeys;

    KeyboardState();

    // Init keyboard state using SDL
    // Be sure SDL is correctly initialized
    // This should be called once
    void init();

    // Destroy keyboard state
    // init should be called before
    void destroy();

    // Clears key events state
    // This should be called at the end of each frame
    // to avoid handling already processed events
    void clearKeyEvents();

    // Updates keyboard state according a keyboard event
    void handleKeyboardEvent(const SDL_KeyboardEvent& event);

    // Returns true if a key press event was received and 
    // belongs to key with this key code
    bool keyPressedEvent(const SDL_Keycode code);

    // Returns true if a key release event was received and 
    // belongs to key with this key code
    bool keyReleasedEvent(const SDL_Keycode code); 

    // Returns true if key is pressed
    bool keyPressed(const SDL_Keycode code);

private:
    KeyboardState(const KeyboardState& src);
    const KeyboardState& operator=(const KeyboardState& src);
};